namespace RBAC.Read.Api.Application.Handler.ERP.InboundManagement
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.Domain.MaterialManage;
    using RBAC.Domain.StorageManage;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.ERP.InboundManagement;
    using RBAC.Read.Api.Application.Dto.ERP;

    /// <summary>
    /// 根据ID获取采购入库详情 处理器
    /// </summary>
    public class GetPurchaseStorageByIdHandler : IRequestHandler<GetPurchaseStorageByIdCommand, APIResult<PurchaseStorageDetailDto>>
    {
        private readonly IBaseRepository<PurchaseStorage> headerRepo;
        private readonly IBaseRepository<PurchaseStorageDetail> detailRepo;
        private readonly IBaseRepository<Mater> materRepo;
        private readonly ILogger<GetPurchaseStorageByIdHandler> logger;

        public GetPurchaseStorageByIdHandler(
            IBaseRepository<PurchaseStorage> headerRepo,
            IBaseRepository<PurchaseStorageDetail> detailRepo,
            IBaseRepository<Mater> materRepo,
            ILogger<GetPurchaseStorageByIdHandler> logger)
        {
            this.headerRepo = headerRepo;
            this.detailRepo = detailRepo;
            this.materRepo = materRepo;
            this.logger = logger;
        }

        public Task<APIResult<PurchaseStorageDetailDto>> Handle(GetPurchaseStorageByIdCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<PurchaseStorageDetailDto>();
            try
            {
                logger.LogInformation("开始获取采购入库详情 Id={Id}", request.Id);

                // 主表
                var header = headerRepo.GetFirstOrDefault("Id = @Id", new { Id = request.Id });
                if (header == null)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "未找到对应的采购入库单";
                    result.Data = null;
                    return Task.FromResult(result);
                }

                // 明细
                var details = detailRepo.GetAll("PurchaseStorageId = @PurchaseStorageId", new { PurchaseStorageId = header.Id });

                // 物料
                var materIds = details.Select(d => d.MaterId).Distinct().ToList();
                var materMap = new Dictionary<long, Mater>();
                if (materIds.Any())
                {
                    var inClause = string.Join(",", materIds.Select((_, index) => $"@Id{index}"));
                    var parameters = materIds.Select((id, index) => new { Key = $"@Id{index}", Value = id })
                        .ToDictionary(x => x.Key, x => (object)x.Value);
                    var maters = materRepo.GetAll($"Id IN ({inClause})", parameters);
                    materMap = maters.ToDictionary(m => m.Id, m => m);
                }

                var dto = new PurchaseStorageDetailDto
                {
                    Id = header.Id,
                    OrderCode = header.OrderCode,
                    OrderDate = header.OrderDate,
                    OrderStatus = header.OrderStatus,
                    BusinessStatus = header.BusinessStatus,
                    Warehouse = header.Warehouse,
                    ArrivalNo = header.ArrivalNo,
                    Operator = header.Operator,
                    Supplier = header.Supplier,
                    BusinessDept = header.BusinessDept,
                    BusinessPerson = header.BusinessPerson,
                    Remark = header.Remark,
                    Items = details.Select(d =>
                    {
                        materMap.TryGetValue(d.MaterId, out var m);
                        return new PurchaseStorageDetailItemDto
                        {
                            Id = d.Id,
                            MaterId = d.MaterId,
                            MaterCode = m?.MaterCode,
                            MaterName = m?.MaterName,
                            Unit = m?.Unit,
                            ModelSpec = m?.ModelSpec,
                            SalesOrderCode = d.SalesOrderCode,
                            Num = d.Num,
                            Remark = d.Remark
                        };
                    }).ToList()
                };

                result.Code = APIEnums.Success;
                result.Msg = "获取采购入库详情成功";
                result.Data = dto;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取采购入库详情失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取采购入库详情失败";
                result.Data = null;
            }

            return Task.FromResult(result);
        }
    }
}
